<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>WebSocket全功能聊天室</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            min-height: 100vh;
            padding: 20px;
        }

        .container {
            max-width: 1200px;
            margin: 0 auto;
            background-color: rgba(255, 255, 255, 0.95);
            border-radius: 20px;
            box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
            overflow: hidden;
            display: flex;
            min-height: 90vh;
        }

        .sidebar {
            width: 300px;
            background: linear-gradient(180deg, #4a5568 0%, #2d3748 100%);
            color: white;
            padding: 25px;
            display: flex;
            flex-direction: column;
        }

        .main-content {
            flex: 1;
            display: flex;
            flex-direction: column;
            min-width: 0;
            overflow: hidden;
        }

        .header {
            padding: 25px;
            background-color: #f7fafc;
            border-bottom: 1px solid #e2e8f0;
        }
        
        .data-monitor {
            background-color: #f1f5f9;
            border: 1px solid #e2e8f0;
            border-radius: 8px;
            margin: 15px 0;
            padding: 15px;
            max-height: 200px;
            overflow-y: auto;
            overflow-x: hidden;
            min-width: 0;
        }
        
        .data-monitor h4 {
            margin-bottom: 10px;
            color: #475569;
        }
        
        .data-item {
            padding: 8px;
            margin: 5px 0;
            border-radius: 4px;
            font-family: 'Courier New', monospace;
            font-size: 12px;
            white-space: pre-wrap;
            word-wrap: break-word;
            word-break: break-all;
            overflow-wrap: break-word;
            max-width: 100%;
            box-sizing: border-box;
        }
        
        .data-item.sent {
            background-color: #dbeafe;
            border-left: 4px solid #3b82f6;
        }
        
        .data-item.received {
            background-color: #d1fae5;
            border-left: 4px solid #10b981;
        }
        
        .data-item.error {
            background-color: #fee2e2;
            border-left: 4px solid #ef4444;
        }
        
        .data-item-header {
            font-weight: bold;
            margin-bottom: 4px;
            font-size: 11px;
        }
        
        .data-item-content {
            overflow-x: hidden;
            word-wrap: break-word;
            word-break: break-all;
            overflow-wrap: break-word;
            max-width: 100%;
        }

        .chat-area {
            flex: 1;
            padding: 25px;
            overflow-y: auto;
            overflow-x: hidden;
            background-color: #f8fafc;
            min-width: 0;
        }

        .input-area {
            padding: 20px;
            background-color: #fff;
            border-top: 1px solid #e2e8f0;
        }

        h1 {
            font-size: 28px;
            margin-bottom: 5px;
            color: #2d3748;
        }

        h2 {
            font-size: 20px;
            margin-bottom: 20px;
            color: #4a5568;
        }

        h3 {
            font-size: 18px;
            margin-bottom: 15px;
            color: #e2e8f0;
        }

        .status {
            padding: 10px;
            border-radius: 8px;
            margin-bottom: 20px;
            text-align: center;
            font-weight: bold;
        }

        .status.connected {
            background-color: #48bb78;
            color: white;
        }

        .status.disconnected {
            background-color: #f56565;
            color: white;
        }

        .status.connecting {
            background-color: #ed8936;
            color: white;
        }

        .control-panel {
            background-color: rgba(255, 255, 255, 0.1);
            border-radius: 10px;
            padding: 15px;
            margin-bottom: 20px;
        }

        .panel-section {
            margin-bottom: 20px;
        }

        input, select, button {
            width: 100%;
            padding: 12px;
            margin-bottom: 10px;
            border: 1px solid #cbd5e0;
            border-radius: 8px;
            font-size: 14px;
            transition: all 0.3s;
        }

        input:focus, select:focus {
            outline: none;
            border-color: #667eea;
            box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.2);
        }

        button {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            border: none;
            cursor: pointer;
            font-weight: bold;
            transition: all 0.3s;
        }

        button:hover {
            transform: translateY(-2px);
            box-shadow: 0 10px 20px rgba(102, 126, 234, 0.2);
        }

        button:active {
            transform: translateY(0);
        }

        button:disabled {
            background: #a0aec0;
            cursor: not-allowed;
            transform: none;
            box-shadow: none;
        }

        .btn-secondary {
            background: linear-gradient(135deg, #4299e1 0%, #3182ce 100%);
        }

        .btn-danger {
            background: linear-gradient(135deg, #f56565 0%, #e53e3e 100%);
        }

        .btn-success {
            background: linear-gradient(135deg, #48bb78 0%, #38a169 100%);
        }

        .message {
            margin-bottom: 15px;
            padding: 15px;
            border-radius: 10px;
            max-width: 80%;
            width: auto;
            display: inline-block;
            word-wrap: break-word;
            box-sizing: border-box;
            overflow: hidden;
        }

        .message.sent {
            background-color: #667eea;
            color: white;
            float: right;
            clear: both;
            border-bottom-right-radius: 5px;
        }

        .message.received {
            background-color: #e2e8f0;
            color: #2d3748;
            float: left;
            clear: both;
            border-bottom-left-radius: 5px;
        }

        .message.system {
            background-color: #48bb78;
            color: white;
            text-align: left;
            max-width: 70%;
            width: auto;
            float: left;
            clear: both;
            font-style: normal;
            word-wrap: break-word;
            word-break: break-all;
            overflow-wrap: break-word;
            border-radius: 18px 18px 18px 5px;
        }
        
        .message.system .message-header {
            color: rgba(255, 255, 255, 0.9);
        }

        .message-header {
            font-size: 12px;
            margin-bottom: 5px;
            opacity: 0.8;
        }

        .message-content {
            font-size: 16px;
            line-height: 1.5;
            overflow-wrap: break-word;
            word-wrap: break-word;
            word-break: break-word;
            max-width: 100%;
            overflow: hidden;
        }

        .message-content img {
            display: block;
            max-width: 100%;
            height: auto;
        }

        .rooms-list, .users-list {
            list-style: none;
            max-height: 200px;
            overflow-y: auto;
            background-color: rgba(255, 255, 255, 0.1);
            border-radius: 8px;
            padding: 10px;
            margin-bottom: 15px;
        }

        .room-item, .user-item {
            padding: 8px 12px;
            margin-bottom: 8px;
            background-color: rgba(255, 255, 255, 0.2);
            border-radius: 6px;
            display: flex;
            justify-content: space-between;
            align-items: center;
        }

        .room-item.active, .user-item.me {
            background-color: rgba(102, 126, 234, 0.5);
            font-weight: bold;
        }

        .room-name {
            font-weight: bold;
        }

        .room-count {
            background-color: rgba(255, 255, 255, 0.3);
            padding: 2px 8px;
            border-radius: 12px;
            font-size: 12px;
        }

        .tab-container {
            display: flex;
            border-bottom: 1px solid #e2e8f0;
            margin-bottom: 20px;
        }

        .tab {
            padding: 12px 24px;
            cursor: pointer;
            font-weight: bold;
            color: #718096;
            border-bottom: 3px solid transparent;
            transition: all 0.3s;
        }

        .tab.active {
            color: #667eea;
            border-bottom-color: #667eea;
        }

        .tab-content {
            display: none;
        }

        .tab-content.active {
            display: block;
        }

        .message-form {
            display: flex;
            gap: 10px;
            width: 100%;
        }

        .message-input {
            flex: 1;
        }

        .file-upload {
            position: relative;
            width: 100px;
        }

        .file-upload input {
            position: absolute;
            width: 100%;
            height: 100%;
            opacity: 0;
            cursor: pointer;
        }

        .file-upload button {
            width: 100%;
            background: linear-gradient(135deg, #ed8936 0%, #dd6b20 100%);
        }

        .metrics {
            background-color: #f7fafc;
            border-radius: 10px;
            padding: 15px;
            margin-top: 20px;
            font-size: 14px;
        }

        .metric-item {
            display: flex;
            justify-content: space-between;
            margin-bottom: 8px;
            padding-bottom: 8px;
            border-bottom: 1px solid #e2e8f0;
        }

        .metric-label {
            color: #4a5568;
        }

        .metric-value {
            font-weight: bold;
            color: #2d3748;
        }

        .notification {
            position: fixed;
            top: 20px;
            right: 20px;
            padding: 15px 25px;
            border-radius: 8px;
            background-color: #2d3748;
            color: white;
            box-shadow: 0 10px 25px rgba(0, 0, 0, 0.2);
            z-index: 1000;
            transform: translateX(120%);
            transition: transform 0.4s;
        }

        .notification.show {
            transform: translateX(0);
        }

        .notification.success {
            background-color: #48bb78;
        }

        .notification.error {
            background-color: #f56565;
        }

        .notification.info {
            background-color: #4299e1;
        }

        .image-modal {
            display: none;
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background-color: rgba(0, 0, 0, 0.9);
            z-index: 2000;
            justify-content: center;
            align-items: center;
            flex-direction: column;
        }

        .image-modal.show {
            display: flex;
        }

        .image-modal-content {
            position: relative;
            max-width: 80%;
            max-height: 80%;
            z-index: 5;
        }

        .image-modal img {
            max-width: 100%;
            max-height: 100%;
            object-fit: contain;
            border-radius: 8px;
            box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
        }

        .image-modal-close {
            position: absolute;
            top: 5px;
            right: 5px;
            width: 40px !important;
            height: 40px !important;
            min-width: 40px !important;
            max-width: 40px !important;
            font-size: 25px;
            color: white;
            cursor: pointer;
            background: rgba(0, 0, 0, 0.5);
            border: 2px solid white;
            border-radius: 50%;
            display: flex;
            align-items: center;
            justify-content: center;
            transition: all 0.3s;
            z-index: 10 !important;
            pointer-events: auto !important;
            user-select: none;
            -webkit-user-select: none;
            -moz-user-select: none;
            -ms-user-select: none;
            padding: 0 !important;
            margin: 0 !important;
        }

        .image-modal-close:hover {
            background: rgba(245, 101, 101, 0.7);
            border-color: white;
            transform: scale(1.1);
        }

        .image-modal-filename {
            color: white;
            margin-top: 20px;
            font-size: 16px;
            text-align: center;
            max-width: 90%;
            word-wrap: break-word;
        }

        @media (max-width: 768px) {
            .container {
                flex-direction: column;
                min-height: auto;
            }
            
            .sidebar {
                width: 100%;
                order: 2;
            }
            
            .main-content {
                order: 1;
            }
        }
    </style>
</head>
<body>
    <div class="image-modal" id="imageModal">
        <div class="image-modal-content">
            <button class="image-modal-close" id="imageModalClose" type="button" onclick="closeImageModal(); return false;">&times;</button>
            <img id="imageModalImg" src="" alt="放大图片">
        </div>
        <div class="image-modal-filename" id="imageModalFilename"></div>
    </div>
    
    <div class="container">
        <!-- 侧边栏 -->
        <div class="sidebar">
            <h3>聊天室控制台</h3>
            
            <!-- 连接状态 -->
            <div class="status disconnected" id="status">未连接</div>
            
            <!-- 连接控制面板 -->
            <div class="control-panel">
                <div class="panel-section">
                    <h3>连接设置</h3>
                    <input type="text" id="clientId" placeholder="客户端ID (数字)" value="1001">
                    <input type="text" id="username" placeholder="用户名" value="用户1001">
                    <button id="connectBtn">连接服务器</button>
                    <button id="disconnectBtn" disabled>断开连接</button>
                </div>
                
                <div class="panel-section">
                    <h3>房间管理</h3>
                    <input type="text" id="roomName" placeholder="房间名称">
                    <button id="createRoomBtn" class="btn-success" disabled>创建房间</button>
                    <button id="leaveRoomBtn" class="btn-danger" disabled>离开房间</button>
                </div>
                
                <div class="panel-section">
                    <h3>房间列表</h3>
                    <div class="rooms-list" id="roomsList">
                        <!-- 房间列表将动态生成 -->
                    </div>
                    <button id="refreshRoomsBtn" disabled>刷新房间</button>
                </div>
                
                <div class="panel-section">
                    <h3>在线用户</h3>
                    <div class="users-list" id="usersList">
                        <!-- 用户列表将动态生成 -->
                    </div>
                    <button id="refreshUsersBtn" disabled>刷新用户</button>
                </div>
            </div>
            
            <!-- 服务器指标 -->
            <div class="metrics">
                <h3>服务器状态</h3>
                <div class="metric-item">
                    <span class="metric-label">连接状态:</span>
                    <span class="metric-value" id="serverStatus">未连接</span>
                </div>
                <div class="metric-item">
                    <span class="metric-label">连接数:</span>
                    <span class="metric-value" id="connectionCount">0</span>
                </div>
                <div class="metric-item">
                    <span class="metric-label">房间数:</span>
                    <span class="metric-value" id="roomCount">0</span>
                </div>
                <div class="metric-item">
                    <span class="metric-label">消息数:</span>
                    <span class="metric-value" id="messageCount">0</span>
                </div>
            </div>
        </div>
        
        <!-- 主内容区 -->
        <div class="main-content">
            <div class="header">
                <h1>WebSocket全功能聊天室</h1>
                <h2 id="currentRoom">未加入房间</h2>
                
                <!-- 数据监控区域 -->
                <div class="data-monitor" id="dataMonitor">
                    <h4>WebSocket消息监控</h4>
                    <div id="dataMonitorContent">
                        <div style="text-align: center; color: #94a3b8; padding: 20px;">等待WebSocket消息...</div>
                    </div>
                </div>
            </div>
            
            <!-- 标签页 -->
            <div class="tab-container">
                <div class="tab active" data-tab="chat">聊天室</div>
                <div class="tab" data-tab="rooms">房间管理</div>
                <div class="tab" data-tab="users">用户管理</div>
                <div class="tab" data-tab="admin">管理员</div>
            </div>
            
            <!-- 聊天室标签页 -->
            <div class="tab-content active" id="chat-tab">
                <div class="chat-area" id="chatArea">
                    <div class="message system">
                        <div class="message-header">系统消息</div>
                        <div class="message-content">欢迎使用WebSocket聊天室！</div>
                    </div>
                </div>
                
                <div class="input-area" style="position: relative;">
                    <div class="message-form">
                        <div style="width:100%;display: flex; flex-direction: column; gap: 10px; margin-bottom: 10px;">
                            <!-- 输入框 -->
                            <textarea id="messageInput" placeholder="输入消息..." style="width: 100%; min-width: 600px; min-height: 60px; resize: vertical;" disabled></textarea>
                            
                            <!-- 按钮区域 -->
                            <div style="display: flex; align-items: center; gap: 10px; justify-content: space-between;">
                                <div style="display: flex; align-items: center; gap: 10px;width: 200px;">
                                    <button id="emojiBtn" class="btn-secondary" style="width: auto; padding: 8px 12px;" disabled>😊</button>
                                    <button id="sendBtn" disabled style="120px;">发送消息</button>
                                </div>
                                <div style="display: flex; gap: 10px;">
                                    <div class="file-upload" style="width: 120px;">
                                        <input type="file" id="fileInput" disabled>
                                        <button style="120px;">发送图片</button>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                    
                    <!-- 表情选择器 -->
                    <div id="emojiPicker" class="emoji-picker" style="display: none; position: absolute; background: white; border: 1px solid #e2e8f0; border-radius: 8px; padding: 10px; box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); z-index: 1000;">
                        <div class="emoji-grid" style="display: grid; grid-template-columns: repeat(6, 1fr); gap: 8px; width: 240px;">
                            <!-- 常用表情 -->
                            <span class="emoji-item" style="cursor: pointer; font-size: 22px; text-align: center; padding: 8px; border-radius: 4px; hover: background-color: #f1f5f9; display: inline-block; width: 32px; height: 32px; box-sizing: border-box;">😊</span>
                            <span class="emoji-item" style="cursor: pointer; font-size: 22px; text-align: center; padding: 8px; border-radius: 4px; hover: background-color: #f1f5f9; display: inline-block; width: 32px; height: 32px; box-sizing: border-box;">😂</span>
                            <span class="emoji-item" style="cursor: pointer; font-size: 22px; text-align: center; padding: 8px; border-radius: 4px; hover: background-color: #f1f5f9; display: inline-block; width: 32px; height: 32px; box-sizing: border-box;">😍</span>
                            <span class="emoji-item" style="cursor: pointer; font-size: 22px; text-align: center; padding: 8px; border-radius: 4px; hover: background-color: #f1f5f9; display: inline-block; width: 32px; height: 32px; box-sizing: border-box;">🤔</span>
                            <span class="emoji-item" style="cursor: pointer; font-size: 22px; text-align: center; padding: 8px; border-radius: 4px; hover: background-color: #f1f5f9; display: inline-block; width: 32px; height: 32px; box-sizing: border-box;">😢</span>
                            <span class="emoji-item" style="cursor: pointer; font-size: 22px; text-align: center; padding: 8px; border-radius: 4px; hover: background-color: #f1f5f9; display: inline-block; width: 32px; height: 32px; box-sizing: border-box;">👍</span>
                            <span class="emoji-item" style="cursor: pointer; font-size: 22px; text-align: center; padding: 8px; border-radius: 4px; hover: background-color: #f1f5f9; display: inline-block; width: 32px; height: 32px; box-sizing: border-box;">👎</span>
                            <span class="emoji-item" style="cursor: pointer; font-size: 22px; text-align: center; padding: 8px; border-radius: 4px; hover: background-color: #f1f5f9; display: inline-block; width: 32px; height: 32px; box-sizing: border-box;">🎉</span>
                            <span class="emoji-item" style="cursor: pointer; font-size: 22px; text-align: center; padding: 8px; border-radius: 4px; hover: background-color: #f1f5f9; display: inline-block; width: 32px; height: 32px; box-sizing: border-box;">🔥</span>
                            <span class="emoji-item" style="cursor: pointer; font-size: 22px; text-align: center; padding: 8px; border-radius: 4px; hover: background-color: #f1f5f9; display: inline-block; width: 32px; height: 32px; box-sizing: border-box;">❤️</span>
                            <span class="emoji-item" style="cursor: pointer; font-size: 22px; text-align: center; padding: 8px; border-radius: 4px; hover: background-color: #f1f5f9; display: inline-block; width: 32px; height: 32px; box-sizing: border-box;">💔</span>
                            <span class="emoji-item" style="cursor: pointer; font-size: 22px; text-align: center; padding: 8px; border-radius: 4px; hover: background-color: #f1f5f9; display: inline-block; width: 32px; height: 32px; box-sizing: border-box;">👍🏻</span>
                            <span class="emoji-item" style="cursor: pointer; font-size: 22px; text-align: center; padding: 8px; border-radius: 4px; hover: background-color: #f1f5f9; display: inline-block; width: 32px; height: 32px; box-sizing: border-box;">👎🏻</span>
                            <span class="emoji-item" style="cursor: pointer; font-size: 22px; text-align: center; padding: 8px; border-radius: 4px; hover: background-color: #f1f5f9; display: inline-block; width: 32px; height: 32px; box-sizing: border-box;">👏</span>
                            <span class="emoji-item" style="cursor: pointer; font-size: 22px; text-align: center; padding: 8px; border-radius: 4px; hover: background-color: #f1f5f9; display: inline-block; width: 32px; height: 32px; box-sizing: border-box;">🙏</span>
                            <span class="emoji-item" style="cursor: pointer; font-size: 22px; text-align: center; padding: 8px; border-radius: 4px; hover: background-color: #f1f5f9; display: inline-block; width: 32px; height: 32px; box-sizing: border-box;">🤣</span>
                        </div>
                    </div>
                    
                    <div style="display: flex; gap: 10px; margin-top: 10px;">
                        <button id="clearChatBtn" class="btn-secondary" disabled>清空聊天</button>
                        <button id="broadcastBtn" class="btn-secondary" disabled>全局广播</button>
                    </div>
                </div>
            </div>
            
            <!-- 房间管理标签页 -->
            <div class="tab-content" id="rooms-tab">
                <div class="chat-area">
                    <h2>房间管理</h2>
                    <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 20px;">
                        <div>
                            <h3>创建房间</h3>
                            <input type="text" id="newRoomName" placeholder="新房间名称">
                            <input type="number" id="maxUsers" placeholder="最大人数 (0=无限制)" value="0" min="0">
                            <button id="createRoomBtn2" class="btn-success" disabled>创建房间</button>
                        </div>
                        <div>
                            <h3>房间操作</h3>
                            <select id="roomSelect" disabled>
                                <option value="">选择房间</option>
                            </select>
                            <button id="joinRoomBtn" class="btn-secondary" disabled>加入房间</button>
                            <button id="deleteRoomBtn" class="btn-danger" disabled>删除房间</button>
                            <button id="updateRoomBtn" class="btn-secondary" disabled>修改名称</button>
                        </div>
                    </div>
                    
                    <h3 style="margin-top: 30px;">房间详情</h3>
                    <div id="roomDetails" style="background-color: #f7fafc; padding: 15px; border-radius: 8px;">
                        选择一个房间查看详情
                    </div>
                </div>
            </div>
            
            <!-- 用户管理标签页 -->
            <div class="tab-content" id="users-tab">
                <div class="chat-area">
                    <h2>用户管理</h2>
                    <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 20px;">
                        <div>
                            <h3>用户权限</h3>
                            <input type="number" id="targetUserId" placeholder="目标用户ID">
                            <select id="permissionSelect">
                                <option value="0">普通用户</option>
                                <option value="1">房主</option>
                                <option value="2">房间管理员</option>
                                <option value="4">全局管理员</option>
                                <option value="8">系统管理员</option>
                            </select>
                            <button id="setPermissionBtn" class="btn-secondary" disabled>设置权限</button>
                            <button id="getPermissionBtn" class="btn-secondary" disabled>查询权限</button>
                        </div>
                        <div>
                            <h3>用户操作</h3>
                            <input type="number" id="kickUserId" placeholder="要踢出的用户ID">
                            <button id="kickUserBtn" class="btn-danger" disabled>踢出用户</button>
                            <button id="listUsersBtn" class="btn-secondary" disabled>列出所有用户</button>
                        </div>
                    </div>
                    
                    <h3 style="margin-top: 30px;">用户列表</h3>
                    <div id="userDetails" style="background-color: #f7fafc; padding: 15px; border-radius: 8px; max-height: 300px; overflow-y: auto;">
                        用户列表将显示在这里
                    </div>
                </div>
            </div>
            
            <!-- 管理员标签页 -->
            <div class="tab-content" id="admin-tab">
                <div class="chat-area">
                    <h2>服务器管理</h2>
                    <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 20px;">
                        <div>
                            <h3>服务器控制</h3>
                            <button id="getMetricsBtn" class="btn-secondary" disabled>获取服务器指标</button>
                            <button id="getAllRoomsBtn" class="btn-secondary" disabled>获取所有房间</button>
                            <button id="stopServerBtn" class="btn-danger" disabled>停止服务器</button>
                        </div>
                        <div>
                            <h3>广播消息</h3>
                            <input type="text" id="broadcastMessage" placeholder="广播消息内容">
                            <button id="sendBroadcastBtn" class="btn-success" disabled>发送广播</button>
                        </div>
                    </div>
                    
                    <h3 style="margin-top: 30px;">服务器指标</h3>
                    <div id="serverMetrics" style="background-color: #f7fafc; padding: 15px; border-radius: 8px; font-family: monospace; white-space: pre-wrap;">
                        点击"获取服务器指标"查看
                    </div>
                </div>
            </div>
        </div>
    </div>
    
    <!-- 通知区域 -->
    <div class="notification" id="notification"></div>

    <script>
        // WebSocket连接和相关状态
        let ws = null;
        let clientId = 0;
        let username = "";
        let currentRoomId = 0;
        let currentRoomName = "";
        let messageCount = 0;
        let reconnectAttempts = 0;
        let maxReconnectAttempts = 5;
        let reconnectDelay = 3000;
        let heartbeatInterval = null;
        let lastHeartbeatTime = 0;
        const HEARTBEAT_INTERVAL = 30000; // 30秒
        
        // DOM元素
        const statusElement = document.getElementById('status');
        const chatArea = document.getElementById('chatArea');
        const messageInput = document.getElementById('messageInput');
        const sendBtn = document.getElementById('sendBtn');
        const connectBtn = document.getElementById('connectBtn');
        const disconnectBtn = document.getElementById('disconnectBtn');
        const roomsList = document.getElementById('roomsList');
        const usersList = document.getElementById('usersList');
        const fileInput = document.getElementById('fileInput');
        const currentRoomElement = document.getElementById('currentRoom');
        const serverStatusElement = document.getElementById('serverStatus');
        const connectionCountElement = document.getElementById('connectionCount');
        const roomCountElement = document.getElementById('roomCount');
        const messageCountElement = document.getElementById('messageCount');
        const notificationElement = document.getElementById('notification');
        
        // 数据监控元素
        const dataMonitorContent = document.getElementById('dataMonitorContent');
        
        // 按钮元素
        const clearChatBtn = document.getElementById('clearChatBtn');
        const broadcastBtn = document.getElementById('broadcastBtn');
        const createRoomBtn = document.getElementById('createRoomBtn');
        const createRoomBtn2 = document.getElementById('createRoomBtn2');
        const leaveRoomBtn = document.getElementById('leaveRoomBtn');
        const refreshRoomsBtn = document.getElementById('refreshRoomsBtn');
        const roomSelect = document.getElementById('roomSelect');
        const joinRoomBtn = document.getElementById('joinRoomBtn');
        const deleteRoomBtn = document.getElementById('deleteRoomBtn');
        const updateRoomBtn = document.getElementById('updateRoomBtn');
        const setPermissionBtn = document.getElementById('setPermissionBtn');
        const getPermissionBtn = document.getElementById('getPermissionBtn');
        const kickUserBtn = document.getElementById('kickUserBtn');
        const listUsersBtn = document.getElementById('listUsersBtn');
        const refreshUsersBtn = document.getElementById('refreshUsersBtn');
        const getMetricsBtn = document.getElementById('getMetricsBtn');
        const getAllRoomsBtn = document.getElementById('getAllRoomsBtn');
        const stopServerBtn = document.getElementById('stopServerBtn');
        const sendBroadcastBtn = document.getElementById('sendBroadcastBtn');
        const emojiBtn = document.getElementById('emojiBtn');
        const emojiPicker = document.getElementById('emojiPicker');
        const imageModal = document.getElementById('imageModal');
        const imageModalClose = document.getElementById('imageModalClose');
        const imageModalImg = document.getElementById('imageModalImg');
        const imageModalFilename = document.getElementById('imageModalFilename');
        
        // 图片模态框功能
        if (imageModalClose) {
            imageModalClose.addEventListener('click', function(e) {
                console.log('关闭按钮被点击');
                e.stopPropagation();
                e.preventDefault();
                closeImageModal();
            });
            
            // 确保按钮未被禁用
            imageModalClose.disabled = false;
        }
        
        if (imageModal) {
            imageModal.addEventListener('click', function(e) {
                if (e.target === imageModal) {
                    closeImageModal();
                }
            });
        }
        
        // 按ESC键关闭模态框
        document.addEventListener('keydown', function(e) {
            if (e.key === 'Escape') {
                closeImageModal();
            }
        });
        
        // 标签页切换
        document.querySelectorAll('.tab').forEach(tab => {
            tab.addEventListener('click', () => {
                // 移除所有标签页的active类
                document.querySelectorAll('.tab').forEach(t => t.classList.remove('active'));
                document.querySelectorAll('.tab-content').forEach(c => c.classList.remove('active'));
                
                // 添加当前标签页的active类
                tab.classList.add('active');
                const tabId = tab.getAttribute('data-tab');
                document.getElementById(tabId + "-tab").classList.add('active');
                
                // 隐藏表情选择器
                if (emojiPicker) {
                    emojiPicker.style.display = 'none';
                }
            });
        });
        
        // 表情选择器功能
        if (emojiBtn && emojiPicker) {
            // 切换表情选择器显示/隐藏
            emojiBtn.addEventListener('click', (e) => {
                e.stopPropagation();
                if (emojiPicker.style.display === 'none') {
                    // 显示表情选择器并定位到表情按钮下方
                    const rect = emojiBtn.getBoundingClientRect();
                    const inputArea = document.querySelector('.input-area');
                    const inputAreaRect = inputArea.getBoundingClientRect();
                    
                    // 计算相对于input-area的位置
                    let left = rect.left - inputAreaRect.left;
                    let top = rect.bottom - inputAreaRect.top + 5;
                    
                    // 确保表情选择器不会超出窗口
                    const pickerWidth = 240; // 表情选择器宽度
                    const windowWidth = window.innerWidth;
                    const inputAreaRight = inputAreaRect.left + inputAreaRect.width;
                    
                    if (left + pickerWidth > inputAreaRect.width) {
                        left = inputAreaRect.width - pickerWidth - 10;
                    }
                    
                    emojiPicker.style.left = left + "px";
                    emojiPicker.style.top = top + "px";
                    emojiPicker.style.display = 'block';
                } else {
                    emojiPicker.style.display = 'none';
                }
            });
            
            // 点击表情项插入表情
            document.querySelectorAll('.emoji-item').forEach(item => {
                item.addEventListener('click', (e) => {
                    e.stopPropagation();
                    const emoji = item.textContent;
                    const messageInput = document.getElementById('messageInput');
                    if (messageInput) {
                        // 在光标位置插入表情
                        const start = messageInput.selectionStart;
                        const end = messageInput.selectionEnd;
                        const text = messageInput.value;
                        messageInput.value = text.substring(0, start) + emoji + text.substring(end);
                        messageInput.focus();
                        messageInput.selectionStart = messageInput.selectionEnd = start + emoji.length;
                    }
                    // 隐藏表情选择器
                    emojiPicker.style.display = 'none';
                });
            });
            
            // 点击页面其他地方隐藏表情选择器
            document.addEventListener('click', (e) => {
                if (emojiPicker.style.display === 'block' && 
                    !emojiBtn.contains(e.target) && 
                    !emojiPicker.contains(e.target)) {
                    emojiPicker.style.display = 'none';
                }
            });
        }
        
        // 显示通知
        function showNotification(message, type = 'info', duration = 3000) {
            notificationElement.textContent = message;
            notificationElement.className = "notification " + type + " show";
            
            setTimeout(() => {
                notificationElement.classList.remove('show');
            }, duration);
        }
        
        // 添加消息到数据监控区域
        function addToDataMonitor(message, type = 'received') {
            // 清除初始提示
            if (dataMonitorContent.querySelector('div[style*="text-align: center"]')) {
                dataMonitorContent.innerHTML = '';
            }
            
            // 创建消息元素
            const dataItem = document.createElement('div');
            dataItem.className = "data-item " + type;
            
            // 创建消息头部
            const header = document.createElement('div');
            header.className = 'data-item-header';
            header.textContent = (type === 'sent' ? '发送' : '接收') + " [" + new Date().toLocaleTimeString() + "]";
            
            // 创建消息内容
            const content = document.createElement('div');
            content.className = 'data-item-content';
            
            // 格式化消息内容
            if (typeof message === 'object') {
                content.textContent = JSON.stringify(message, null, 2);
            } else {
                content.textContent = message;
            }
            
            // 组装消息元素
            dataItem.appendChild(header);
            dataItem.appendChild(content);
            
            // 添加到监控区域顶部
            if (dataMonitorContent.firstChild) {
                dataMonitorContent.insertBefore(dataItem, dataMonitorContent.firstChild);
            } else {
                dataMonitorContent.appendChild(dataItem);
            }
            
            // 滚动到顶部，确保最新消息可见
            dataMonitorContent.scrollTop = 0;
            
            // 限制消息数量，只保留最近50条
            const dataItems = dataMonitorContent.querySelectorAll('.data-item');
            if (dataItems.length > 50) {
                // 删除最旧的消息（在底部）
                for (let i = dataItems.length - 1; i >= 50; i--) {
                    dataItems[i].remove();
                }
            }
        }
        
        // 添加消息到聊天区域
        function addMessage(sender, message, type = 'received', isSystem = false, isImage = false) {
            const messageElement = document.createElement('div');
            messageElement.className = "message " + type;
            
            if (isSystem) {
                messageElement.classList.add('system');
            }
            
            const header = document.createElement('div');
            header.className = 'message-header';
            header.textContent = isSystem ? '系统消息：' : sender + " · " + new Date().toLocaleTimeString();
            
            const content = document.createElement('div');
            content.className = 'message-content';
            
            // 确保消息内容不为空
            let displayContent = '无内容';
            
            if (isImage && message !== undefined && message !== null) {
                if (message.data) {
                    let imageUrl;
                    
                    if (message.data.startsWith('data:')) {
                        imageUrl = message.data;
                    } else {
                        const imageType = message.file_type || 'image/jpeg';
                        imageUrl = "data:" + imageType + ";base64," + message.data;
                    }
                    
                    const img = document.createElement('img');
                    img.src = imageUrl;
                    img.alt = message.filename || message.file_name || '图片';
                    img.style.maxWidth = '300px';
                    img.style.maxHeight = '300px';
                    img.style.width = 'auto';
                    img.style.height = 'auto';
                    img.style.borderRadius = '4px';
                    img.style.cursor = 'pointer';
                    img.style.transition = 'transform 0.2s';
                    img.style.display = 'block';
                    
                    img.addEventListener('click', function() {
                        showImageModal(imageUrl, message.filename || message.file_name || '图片', message.file_size || 0);
                    });
                    
                    img.addEventListener('mouseenter', function() {
                        this.style.transform = 'scale(1.05)';
                    });
                    
                    img.addEventListener('mouseleave', function() {
                        this.style.transform = 'scale(1)';
                    });
                    
                    content.appendChild(img);
                    
                    if (message.filename || message.file_name) {
                        const filenameDiv = document.createElement('div');
                        filenameDiv.style.fontSize = '12px';
                        filenameDiv.style.marginTop = '4px';
                        
                        // 构建文件名和大小显示
                        const fileName = message.filename || message.file_name;
                        const fileSize = message.file_size || 0;
                        const displayText = fileName + " (" + formatFileSize(fileSize) + ")";
                        
                        filenameDiv.textContent = displayText;
                        
                        // 根据消息类型设置文件名颜色
                        if (type === 'sent') {
                            filenameDiv.style.color = 'white';
                        } else {
                            filenameDiv.style.color = '#666';
                        }
                        
                        content.appendChild(filenameDiv);
                    }
                } else {
                    displayContent = "图片: " + message.file_name + " (" + message.file_type + ", " + formatFileSize(message.file_size) + ")";
                    content.textContent = displayContent;
                }
            } else if (message !== undefined && message !== null) {
                if (isSystem) {
                    // 系统消息直接显示内容，不解析JSON
                    displayContent = typeof message === 'string' ? message : String(message);
                    // 将换行符转换为 <br> 标签
                    displayContent = displayContent.replace(/\n/g, '<br>');
                    content.innerHTML = displayContent;
                } else {
                    // 检查是否是JSON消息
                    try {
                        // 确保message是字符串
                        const messageStr = typeof message === 'string' ? message : JSON.stringify(message);
                        
                        // 尝试解析JSON
                        try {
                            const parsed = JSON.parse(messageStr);
                            if (parsed.type) {
                                // 检查是否有data字段
                                let dataContent = parsed.data !== undefined ? parsed.data : 
                                                // 检查是否有content字段
                                                (parsed.content !== undefined ? parsed.content : 
                                                 // 检查是否有message字段
                                                 (parsed.message !== undefined ? parsed.message : 
                                                  // 默认值
                                                  '无内容'));
                                displayContent = "<strong>" + parsed.type + ":</strong> " + (typeof dataContent === 'string' ? dataContent : JSON.stringify(dataContent, null, 2));
                                content.innerHTML = displayContent;
                            } else {
                                displayContent = messageStr;
                                // 将换行符转换为 <br> 标签
                                displayContent = displayContent.replace(/\n/g, '<br>');
                                content.innerHTML = displayContent;
                            }
                        } catch {
                            // 如果不是JSON，直接作为文本处理
                            displayContent = messageStr;
                            // 将换行符转换为 <br> 标签
                            displayContent = displayContent.replace(/\n/g, '<br>');
                            content.innerHTML = displayContent;
                        }
                    } catch (e) {
                        // 处理任何错误
                        console.error('处理消息内容时出错:', e);
                        displayContent = typeof message === 'string' ? message : String(message);
                        // 将换行符转换为 <br> 标签
                        displayContent = displayContent.replace(/\n/g, '<br>');
                        content.innerHTML = displayContent;
                    }
                }
            } else {
                displayContent = displayContent.replace(/\n/g, '<br>');
                content.innerHTML = displayContent;
            }
            
            // 确保元素被正确添加
            messageElement.appendChild(header);
            messageElement.appendChild(content);
            
            // 确保chatArea存在
            if (chatArea) {
                chatArea.appendChild(messageElement);
                
                // 滚动到底部
                chatArea.scrollTop = chatArea.scrollHeight;
                
                // 更新消息计数
                if (!isSystem) {
                    messageCount++;
                    if (messageCountElement) {
                        messageCountElement.textContent = messageCount;
                    }
                }
            }
        }
        
        // 显示图片模态框
        function showImageModal(imageUrl, filename, fileSize = 0) {
            const modal = document.getElementById('imageModal');
            const modalImg = document.getElementById('imageModalImg');
            const modalFilename = document.getElementById('imageModalFilename');
            
            modalImg.src = imageUrl;
            
            // 构建文件名和大小显示
            const displayText = fileSize > 0 ? filename + " (" + formatFileSize(fileSize) + ")" : filename;
            modalFilename.textContent = displayText;
            
            modal.classList.add('show');
        }
        
        // 关闭图片模态框
        function closeImageModal() {
            const modal = document.getElementById('imageModal');
            modal.classList.remove('show');
        }
        
        // 消息超时管理
        const messageTimeouts = new Map();
        const MESSAGE_TIMEOUT = 10000; // 10秒超时
        
        // 发送WebSocket消息（带监控和超时检测）
        function sendWebSocketMessage(message) {
            if (!ws || ws.readyState !== WebSocket.OPEN) {
                showNotification('WebSocket未连接', 'error');
                return false;
            }
            
            try {
                const messageStr = JSON.stringify(message);
                ws.send(messageStr);
                addToDataMonitor(message, 'sent');
                
                // 设置超时检测（对于需要响应的消息）
                if (message.type !== 'ping' && message.type !== 'chat' && message.type !== 'chat_message') {
                    const timeoutId = setTimeout(() => {
                        const timeoutMessage = "发送超时: " + message.type + " 请求未收到响应";
                        showNotification(timeoutMessage, 'error');
                        addToDataMonitor(timeoutMessage, 'error');
                    }, MESSAGE_TIMEOUT);
                    
                    // 存储超时ID，用于后续清除
                    const messageKey = message.type + (message.room_id || '') + (message.target_user_id || '');
                    messageTimeouts.set(messageKey, timeoutId);
                }
                
                return true;
            } catch (error) {
                console.error('发送WebSocket消息失败:', error);
                showNotification('发送消息失败', 'error');
                addToDataMonitor("发送失败: " + error.message, 'error');
                return false;
            }
        }
        
        // 清除消息超时
        function clearMessageTimeout(responseMessage) {
            if (!responseMessage || !responseMessage.type) return;
            
            // 根据响应类型清除对应的请求超时
            let messageKey = '';
            switch (responseMessage.type) {
                case 'rooms_list':
                    messageKey = 'get_rooms';
                    break;
                case 'users_list':
                    messageKey = 'get_users';
                    break;
                case 'metrics':
                    messageKey = 'get_metrics';
                    break;
                case 'room_created':
                    messageKey = 'create_room';
                    break;
                case 'room_deleted':
                    messageKey = 'delete_room' + responseMessage.data.room_id;
                    break;
                case 'room_updated':
                    messageKey = 'update_room' + responseMessage.data.room_id;
                    break;
                case 'room_joined':
                    messageKey = 'join_room' + responseMessage.data.room_id;
                    break;
                case 'room_left':
                    messageKey = 'leave_room';
                    break;
                case 'broadcast':
                case 'global_broadcast_response':
                case 'system_message':
                    messageKey = 'global_broadcast';
                    break;
                case 'file':
                    messageKey = 'file';
                    break;
                case 'error':
                    // 错误消息，清除所有超时
                    clearAllMessageTimeouts();
                    return;
            }
            
            if (messageKey && messageTimeouts.has(messageKey)) {
                clearTimeout(messageTimeouts.get(messageKey));
                messageTimeouts.delete(messageKey);
            }
        }
        
        // 清除所有消息超时
        function clearAllMessageTimeouts() {
            messageTimeouts.forEach(timeoutId => clearTimeout(timeoutId));
            messageTimeouts.clear();
        }
        
        // 连接WebSocket服务器
        function connect() {
            const clientIdInput = document.getElementById('clientId').value.trim();
            const usernameInput = document.getElementById('username').value.trim();
            
            if (!clientIdInput || !usernameInput) {
                showNotification('请输入客户端ID和用户名', 'error');
                return;
            }
            
            // 验证sender长度（用户名）
            if (usernameInput.length > 20) {
                showNotification('发送者名称长度不能超过20个字符', 'error');
                return;
            }
            
            // 验证sender_id是否为整数
            const clientIdNum = parseInt(clientIdInput);
            if (isNaN(clientIdNum)) {
                showNotification('发送者ID必须是整数', 'error');
                return;
            }
            
            clientId = clientIdNum;
            username = usernameInput;
            
            // 构建WebSocket URL，包含认证信息
            const wsUrl = "ws://localhost:8088/websocket?client_id=" + clientId + "&user_info=" + encodeURIComponent(JSON.stringify({name: username}));
            
            ws = new WebSocket(wsUrl);
            
            // 更新UI状态
            statusElement.textContent = '连接中...';
            statusElement.className = 'status connecting';
            connectBtn.disabled = true;
            disconnectBtn.disabled = false;
            
            // WebSocket事件处理
            ws.onopen = function() {
                statusElement.textContent = '已连接';
                statusElement.className = 'status connected';
                serverStatusElement.textContent = '已连接';
                
                showNotification('成功连接到服务器', 'success');
                addMessage('系统', '已连接到WebSocket服务器', 'system', true);
                
                // 发送用户信息到服务器
                const userInfoMessage = {
                    type: 'user_connected',
                    user_id: clientId,
                    username: username,
                    timestamp: Date.now()
                };
                
                const userInfoMessageStr = JSON.stringify(userInfoMessage);
                ws.send(userInfoMessageStr);
                addToDataMonitor(userInfoMessage, 'sent');
                console.log('发送用户信息:', userInfoMessage);
                
                // 重置重连计数器
                reconnectAttempts = 0;
                
                // 启用相关控件
                enableControls();
                
                // 启动心跳机制
                startHeartbeat();
                
                // 获取房间列表和用户列表
                setTimeout(() => {
                    refreshRooms();
                    refreshUsers();
                    getMetrics();
                }, 500);
            };
            
            ws.onclose = function(event) {
                statusElement.textContent = '未连接';
                statusElement.className = 'status disconnected';
                serverStatusElement.textContent = '未连接';
                
                // 停止心跳
                stopHeartbeat();
                
                const closeMessage = "连接已断开 (代码: " + event.code + ", 原因: " + (event.reason || "未知") + ")";
                showNotification(closeMessage, 'error');
                addMessage('系统', closeMessage, 'system', true);
                
                // 禁用相关控件
                disableControls();
                connectBtn.disabled = false;
                disconnectBtn.disabled = true;
                
                // 尝试重连
                if (reconnectAttempts < maxReconnectAttempts) {
                    reconnectAttempts++;
                    const delay = reconnectDelay * Math.pow(1.5, reconnectAttempts - 1);
                    showNotification("尝试重连 (" + reconnectAttempts + "/" + maxReconnectAttempts + ")...", 'info');
                    setTimeout(connect, delay);
                } else {
                    showNotification('重连失败，请检查服务器状态', 'error');
                }
            };
            
            ws.onerror = function(error) {
                console.error('WebSocket错误:', error);
                const errorMessage = "连接错误: " + (error.message || "未知错误");
                showNotification(errorMessage, 'error');
                addMessage('系统', errorMessage, 'system', true);
            };
            
            ws.onmessage = function(event) {
                try {
                    // 尝试解析JSON消息
                    const message = JSON.parse(event.data);
                    
                    // 添加到数据监控区域
                    addToDataMonitor(message, 'received');
                    
                    // 清除对应消息的超时检测
                    clearMessageTimeout(message);
                    
                    // 更新最后心跳时间
                    lastHeartbeatTime = Date.now();
                    
                    // 根据消息类型处理
                    if (message.type === 'pong') {
                        // 心跳响应，无需处理
                    } else if (message.type === 'room_joined') {
                        currentRoomId = message.data.room_id;
                        currentRoomName = message.data.room_name;
                        currentRoomElement.textContent = "当前房间: " + currentRoomName + " (ID: " + currentRoomId + ")";
                        showNotification("已加入房间: " + currentRoomName, 'success');
                    } else if (message.type === 'room_left') {
                        currentRoomId = 0;
                        currentRoomName = "";
                        currentRoomElement.textContent = '未加入房间';
                        showNotification('已离开房间', 'info');
                    } else if (message.type === 'chat_message') {
                        // 如果不是自己发送的消息，才添加到聊天区域
                        if (message.sender_id !== clientId) {
                            // 将转义的换行符转换回来
                            const content = message.content ? message.content.replace(/\\\\n/g, '\\n') : '';
                            addMessage(message.sender, content, 'received');
                        }
                    } else if (message.type === 'system_message') {
                        // 确保content存在
                        const content = message.content !== undefined ? message.content : '';
                         console.log('收到系统消息:', content);
                         addMessage('系统', content, 'system', true);
                        
                        // 检查消息长度
                        if (content.length > 500) {
                            console.log('系统消息长度超过500个字符，截断处理');
                            content = content.substring(0, 500) + '...';
                        }
                        
                        // 发送响应
                        const responseMessage = {
                            "type": "chat_message",
                            "content": content,
                            "sender": "用户" + clientId,
                            "sender_id": clientId,
                            "room_id": 0,  // 0表示全局消息
                            "timestamp": Date.now()
                        };
                        sendWebSocketMessage(responseMessage);
                    } else if (message.type === 'user_entered') {
                        // 处理用户进入信息
                        console.log('收到用户进入信息:', message);
                        if (message.username && message.user_id) {
                            // 排除自己，自己进入的不显示
                            if (message.user_id !== clientId) {
                                const enterMessage = message.username + " 进入聊天室";
                                addMessage('系统', enterMessage, 'system', true);
                                showNotification(enterMessage, 'info');
                            }
                        }
                    } else if (message.type === 'user_connected') {
                        // 处理用户连接确认信息
                        console.log('收到用户连接确认:', message);
                        if (message.username && message.user_id) {
                            const connectMessage = "用户 " + message.username + " (ID: " + message.user_id + ") 连接成功";
                            addMessage('系统', connectMessage, 'system', true);
                            showNotification(connectMessage, 'success');
                        }
                    } else if (message.type === 'rooms_list') {
                        updateRoomsList(message.data);
                    } else if (message.type === 'users_list') {
                        updateUsersList(message.data);
                    } else if (message.type === 'metrics') {
                        updateMetrics(message.data);
                    } else if (message.type === 'room_created') {
                        // 处理创建房间的响应
                        showNotification("房间创建成功: " + message.data.room_name + " (ID: " + message.data.room_id + ")", 'success');
                        addMessage('系统', "房间创建成功: " + message.data.room_name + " (ID: " + message.data.room_id + ")", 'system', true);
                        // 刷新房间列表
                        setTimeout(refreshRooms, 1000);
                    } else if (message.type === 'room_deleted') {
                        // 处理删除房间的响应
                        showNotification("房间删除成功: ID " + message.data.room_id, 'success');
                        addMessage('系统', "房间删除成功: ID " + message.data.room_id, 'system', true);
                        // 刷新房间列表
                        setTimeout(refreshRooms, 1000);
                    } else if (message.type === 'room_updated') {
                        // 处理修改房间的响应
                        showNotification("房间更新成功: " + message.data.room_name + " (ID: " + message.data.room_id + ")", 'success');
                        addMessage('系统', "房间更新成功: " + message.data.room_name + " (ID: " + message.data.room_id + ")", 'system', true);
                        // 刷新房间列表
                        setTimeout(refreshRooms, 1000);
                    } else if (message.type === 'error') {
                        // 处理错误消息
                        showNotification("错误: " + message.content, 'error');
                        addMessage('系统', "错误: " + message.content, 'system', true);
                    } else if (message.type === 'file') {
                        // 处理文件消息
                        if (message.data) {
                            // 包含文件数据的消息
                            // 检查是否是图片文件（根据文件名后缀或是否有data字段）
                            const fileName = message.filename || message.file_name || '';
                            const isImageFile = fileName.match(/\.(jpg|jpeg|png|gif)$/i) || true; // 默认认为有data的是图片
                            
                            // 判断是否是自己发送的消息
                            const messageType = (message.sender_id && message.sender_id.toString() === clientId.toString()) ? 'sent' : 'received';
                            
                            if (isImageFile) {
                                // 图片文件，显示图片
                                addMessage(message.sender, message, messageType, false, true);
                            } else {
                                // 其他文件，显示文件信息
                                const fileInfo = "文件: " + fileName + " (" + formatFileSize(message.file_size || 0) + ")";
                                addMessage(message.sender, fileInfo, messageType);
                            }
                        } else {
                            // 只包含文件元数据的消息
                            const fileName = message.file_name || message.filename || '';
                            const fileType = message.file_type || '未知类型';
                            const fileSize = message.file_size || 0;
                            const fileInfo = "文件: " + fileName + " (" + fileType + ", " + formatFileSize(fileSize) + ")";
                            
                            // 判断是否是自己发送的消息
                            const messageType = (message.sender_id && message.sender_id.toString() === clientId.toString()) ? 'sent' : 'received';
                            addMessage(message.sender, fileInfo, messageType);
                        }
                    } else {
                        // 通用消息处理
                        addMessage('服务器', JSON.stringify(message, null, 2), 'received');
                    }
                } catch (e) {
                    // 如果不是JSON，则作为普通文本消息处理
                    addMessage('服务器', event.data, 'received');
                    addToDataMonitor(event.data, 'received');
                }
            };
        }
        
        // 启动心跳机制
        function startHeartbeat() {
            // 停止之前的心跳
            stopHeartbeat();
            
            // 发送心跳
            function sendHeartbeat() {
                if (ws && ws.readyState === WebSocket.OPEN) {
                    try {
                        const pingMessage = { type: 'ping' };
                        const messageStr = JSON.stringify(pingMessage);
                        ws.send(messageStr);
                        addToDataMonitor(pingMessage, 'sent');
                        lastHeartbeatTime = Date.now();
                    } catch (error) {
                        console.error('发送心跳失败:', error);
                        addToDataMonitor("发送心跳失败: " + error.message, 'error');
                    }
                }
            }
            
            // 立即发送一次心跳
            sendHeartbeat();
            
            // 设置心跳间隔
            heartbeatInterval = setInterval(sendHeartbeat, HEARTBEAT_INTERVAL);
        }
        
        // 停止心跳机制
        function stopHeartbeat() {
            if (heartbeatInterval) {
                clearInterval(heartbeatInterval);
                heartbeatInterval = null;
            }
        }
        
        // 断开WebSocket连接
        function disconnect() {
            // 停止心跳
            stopHeartbeat();
            
            // 清除所有消息超时
            clearAllMessageTimeouts();
            
            // 重置重连计数器
            reconnectAttempts = maxReconnectAttempts;
            
            if (ws) {
                ws.close();
                ws = null;
            }
        }
        
        // 启用相关控件
        function enableControls() {
            // 聊天相关
            if (messageInput) messageInput.disabled = false;
            if (sendBtn) sendBtn.disabled = false;
            if (emojiBtn) emojiBtn.disabled = false;
            if (fileInput) fileInput.disabled = false;
            if (clearChatBtn) clearChatBtn.disabled = false;
            if (broadcastBtn) broadcastBtn.disabled = false;
            
            // 房间管理
            const roomNameInput = document.getElementById('roomName');
            const newRoomNameInput = document.getElementById('newRoomName');
            const maxUsersInput = document.getElementById('maxUsers');
            if (roomNameInput) roomNameInput.disabled = false;
            if (newRoomNameInput) newRoomNameInput.disabled = false;
            if (maxUsersInput) maxUsersInput.disabled = false;
            if (createRoomBtn) createRoomBtn.disabled = false;
            if (createRoomBtn2) createRoomBtn2.disabled = false;
            if (leaveRoomBtn) leaveRoomBtn.disabled = false;
            if (refreshRoomsBtn) refreshRoomsBtn.disabled = false;
            if (roomSelect) roomSelect.disabled = false;
            if (joinRoomBtn) joinRoomBtn.disabled = false;
            if (deleteRoomBtn) deleteRoomBtn.disabled = false;
            if (updateRoomBtn) updateRoomBtn.disabled = false;
            
            // 用户管理
            const targetUserIdInput = document.getElementById('targetUserId');
            const permissionSelectInput = document.getElementById('permissionSelect');
            const kickUserIdInput = document.getElementById('kickUserId');
            if (targetUserIdInput) targetUserIdInput.disabled = false;
            if (permissionSelectInput) permissionSelectInput.disabled = false;
            if (kickUserIdInput) kickUserIdInput.disabled = false;
            if (setPermissionBtn) setPermissionBtn.disabled = false;
            if (getPermissionBtn) getPermissionBtn.disabled = false;
            if (kickUserBtn) kickUserBtn.disabled = false;
            if (listUsersBtn) listUsersBtn.disabled = false;
            if (refreshUsersBtn) refreshUsersBtn.disabled = false;
            
            // 管理员
            const broadcastMessageInput = document.getElementById('broadcastMessage');
            if (broadcastMessageInput) broadcastMessageInput.disabled = false;
            if (getMetricsBtn) getMetricsBtn.disabled = false;
            if (getAllRoomsBtn) getAllRoomsBtn.disabled = false;
            if (stopServerBtn) stopServerBtn.disabled = false;
            if (sendBroadcastBtn) sendBroadcastBtn.disabled = false;
        }
        
        // 禁用相关控件
        function disableControls() {
            // 禁用所有控件（排除连接按钮和关闭按钮）
            document.querySelectorAll('button:not(#connectBtn):not(#imageModalClose), input:not(#clientId):not(#username)').forEach(el => {
                el.disabled = true;
            });
            
            // 重新启用连接按钮
            connectBtn.disabled = false;
            disconnectBtn.disabled = true;
        }
        
        // 发送消息
        function sendMessage() {
            let message = messageInput.value.trim();
            if (!message || !ws || ws.readyState !== WebSocket.OPEN) return;
            
            // 检查消息长度
            if (message.length > 500) {
                showNotification('消息长度不能超过500个字符', 'error');
                return;
            }
            
            // 转义换行符，将 \n 转换为 \\n
            message = message.replace(/\\n/g, '\\\\n');
            
            // 构建消息对象
            const messageObj = {
                type: 'chat',
                content: message,
                sender: username,
                sender_id: clientId,
                room_id: currentRoomId,
                timestamp: Date.now()
            };
            
            sendWebSocketMessage(messageObj);
            
            // 添加到聊天区域
            addMessage(username, message, 'sent');
            
            // 清空输入框
            messageInput.value = '';
            messageInput.focus();
        }
        
        // 发送文件
        function sendFile(file) {
            if (!file || !ws || ws.readyState !== WebSocket.OPEN) return;
            
            // 允许的文件类型
            const allowedTypes = [
                'image/jpeg',  // JPEG文件
                'image/png',   // PNG文件
                'image/gif'    // GIF文件
            ];
            
            // 文件类型验证
            if (!allowedTypes.includes(file.type)) {
                showNotification("只允许上传JPEG、PNG、GIF格式的图片", 'error');
                return;
            }
            
            // 文件大小验证（500KB限制）
            const maxSize = 500 * 1024; // 500KB
            if (file.size > maxSize) {
                showNotification("文件大小不能超过500KB", 'error');
                return;
            }
            
            const reader = new FileReader();
            reader.onload = function(e) {
                // 构建消息对象
                const messageObj = {
                    type: 'file',
                    file_name: file.name,
                    file_type: file.type,
                    file_size: file.size,
                    sender: username,
                    sender_id: clientId,
                    room_id: currentRoomId,
                    timestamp: Date.now()
                };
                
                // 先发送元数据
                sendWebSocketMessage(messageObj);
                
                // 然后发送文件数据
                ws.send(e.target.result);
                
                // 只有非图片文件才显示发送文件的消息
                if (!file.type.startsWith('image/')) {
                    // 添加到聊天区域
                    addMessage(username, "发送文件: " + file.name + " (" + formatFileSize(file.size) + ")", 'sent');
                }
                
                showNotification("文件 " + file.name + " 已发送", 'success');
            };
            
            reader.readAsArrayBuffer(file);
        }
        
        // 格式化文件大小
        function formatFileSize(bytes) {
            if (bytes === 0) return '0 Bytes';
            
            const k = 1024;
            const sizes = ['Bytes', 'KB', 'MB', 'GB'];
            const i = Math.floor(Math.log(bytes) / Math.log(k));
            
            return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
        }
        
        // 创建房间
        function createRoom() {
            const roomName = document.getElementById('roomName').value.trim() || 
                           document.getElementById('newRoomName').value.trim();
            
            if (!roomName) {
                showNotification('请输入房间名称', 'error');
                return;
            }
            
            // 验证房间名称长度
            if (roomName.length > 20) {
                showNotification('房间名称长度不能超过20个字符', 'error');
                return;
            }
            
            // 构建创建房间请求
            const request = {
                type: 'create_room',
                room_name: roomName,
                max_users: parseInt(document.getElementById('maxUsers').value) || 0,
                creator_id: clientId,
                creator_name: username
            };
            
            const messageStr = JSON.stringify(request);
            ws.send(messageStr);
            addToDataMonitor(JSON.parse(messageStr), 'sent');
            showNotification("正在创建房间: " + roomName, 'info');
        }
        
        // 加入房间
        function joinRoom(roomId) {
            if (!roomId) {
                roomId = document.getElementById('roomSelect').value;
                if (!roomId) {
                    showNotification('请选择房间', 'error');
                    return;
                }
            }
            
            const request = {
                type: 'join_room',
                room_id: parseInt(roomId),
                client_id: clientId,
                client_name: username
            };
            
            const messageStr = JSON.stringify(request);
            ws.send(messageStr);
            addToDataMonitor(JSON.parse(messageStr), 'sent');
        }
        
        // 离开房间
        function leaveRoom() {
            if (!currentRoomId) {
                showNotification('您当前不在任何房间中', 'error');
                return;
            }
            
            const request = {
                type: 'leave_room',
                room_id: currentRoomId,
                client_id: clientId
            };
            
            const messageStr = JSON.stringify(request);
            ws.send(messageStr);
            addToDataMonitor(JSON.parse(messageStr), 'sent');
        }
        
        // 删除房间
        function deleteRoom() {
            const roomId = document.getElementById('roomSelect').value;
            if (!roomId) {
                showNotification('请选择要删除的房间', 'error');
                return;
            }
            
            if (confirm("确定要删除房间ID: " + roomId + " 吗？")) {
                const request = {
                    type: 'delete_room',
                    room_id: parseInt(roomId)
                };
                
                sendWebSocketMessage(request);
                showNotification("正在删除房间ID: " + roomId, 'info');
            }
        }
        
        // 刷新房间列表
        function refreshRooms() {
            const request = { type: 'get_rooms' };
            sendWebSocketMessage(request);
        }
        
        // 更新房间列表显示
        function updateRoomsList(rooms) {
            roomsList.innerHTML = '';
            
            if (!rooms || rooms.length === 0) {
                roomsList.innerHTML = '<div style="text-align: center; padding: 20px; color: #a0aec0;">暂无房间</div>';
                return;
            }
            
            rooms.forEach(room => {
                const roomItem = document.createElement('div');
                roomItem.className = "room-item " + (room.id === currentRoomId ? "active" : "");
                roomItem.innerHTML = "<div><div class=\"room-name\">" + room.name + "</div><div style=\"font-size: 12px; opacity: 0.8;\">ID: " + room.id + "</div></div><div class=\"room-count\">" + room.client_count + "/" + (room.max_clients || "∞") + "</div>";
                
                roomItem.addEventListener('click', () => {
                    if (room.id !== currentRoomId) {
                        joinRoom(room.id);
                    }
                });
                
                roomsList.appendChild(roomItem);
            });
            
            // 同时更新房间选择下拉框
            updateRoomSelect(rooms);
        }
        
        // 更新房间选择下拉框
        function updateRoomSelect(rooms) {
            const roomSelect = document.getElementById('roomSelect');
            roomSelect.innerHTML = '<option value="">选择房间</option>';
            
            rooms.forEach(room => {
                const option = document.createElement('option');
                option.value = room.id;
                option.textContent = room.name + " (ID: " + room.id + ", 人数: " + room.client_count + ")";
                roomSelect.appendChild(option);
            });
        }
        
        // 刷新用户列表
        function refreshUsers() {
            const request = { type: 'get_users' };
            sendWebSocketMessage(request);
        }
        
        // 更新用户列表显示
        function updateUsersList(users) {
            usersList.innerHTML = '';
            
            if (!users || users.length === 0) {
                usersList.innerHTML = '<div style="text-align: center; padding: 20px; color: #a0aec0;">暂无用户</div>';
                return;
            }
            
            users.forEach(user => {
                const userItem = document.createElement('div');
                userItem.className = "user-item " + (user.id === clientId ? "me" : "");
                
                let permissionText = '';
                switch(user.permission) {
                    case 0: permissionText = '普通'; break;
                    case 1: permissionText = '房主'; break;
                    case 2: permissionText = '房间管理员'; break;
                    case 4: permissionText = '全局管理员'; break;
                    case 8: permissionText = '系统管理员'; break;
                    default: permissionText = user.permission;
                }
                
                userItem.innerHTML = "<div><div style=\"font-weight: bold;\">" + (user.name || "用户" + user.id) + "</div><div style=\"font-size: 12px; opacity: 0.8;\">ID: " + user.id + "</div></div><div style=\"font-size: 12px; background-color: rgba(255,255,255,0.3); padding: 2px 8px; border-radius: 12px;\">" + permissionText + "</div>";
                
                usersList.appendChild(userItem);
            });
        }
        
        // 获取服务器指标
        function getMetrics() {
            const request = { type: 'get_metrics' };
            sendWebSocketMessage(request);
        }
        
        // 更新服务器指标显示
        function updateMetrics(metrics) {
            connectionCountElement.textContent = metrics.current_connections || 0;
            roomCountElement.textContent = metrics.current_rooms || 0;
            
            // 更新服务器指标详情
            const metricsDiv = document.getElementById('serverMetrics');
            metricsDiv.textContent = JSON.stringify(metrics, null, 2);
        }
        
        // 设置用户权限
        function setPermission() {
            const targetUserId = document.getElementById('targetUserId').value.trim();
            const permission = document.getElementById('permissionSelect').value;
            
            if (!targetUserId) {
                showNotification('请输入目标用户ID', 'error');
                return;
            }
            
            const request = {
                type: 'set_permission',
                target_user_id: parseInt(targetUserId),
                permission: parseInt(permission)
            };
            
            sendWebSocketMessage(request);
            showNotification("正在为用户 " + targetUserId + " 设置权限 " + permission, 'info');
        }
        
        // 获取用户权限
        function getPermission() {
            const targetUserId = document.getElementById('targetUserId').value.trim();
            
            if (!targetUserId) {
                showNotification('请输入目标用户ID', 'error');
                return;
            }
            
            const request = {
                type: 'get_permission',
                target_user_id: parseInt(targetUserId)
            };
            
            ws.send(JSON.stringify(request));
        }
        
        // 踢出用户
        function kickUser() {
            const kickUserId = document.getElementById('kickUserId').value.trim();
            
            if (!kickUserId) {
                showNotification('请输入要踢出的用户ID', 'error');
                return;
            }
            
            if (confirm("确定要踢出用户ID: " + kickUserId + " 吗？")) {
                const request = {
                    type: 'kick_user',
                    target_user_id: parseInt(kickUserId)
                };
                
                sendWebSocketMessage(request);
                showNotification("正在踢出用户ID: " + kickUserId, 'info');
            }
        }
        
        // 列出所有用户
        function listUsers() {
            const request = { type: 'list_users' };
            sendWebSocketMessage(request);
        }
        
        // 获取所有房间
        function getAllRooms() {
            const request = { type: 'get_all_rooms' };
            sendWebSocketMessage(request);
        }
        
        // 停止服务器
        function stopServer() {
            if (confirm('确定要停止服务器吗？所有连接将被断开！')) {
                const request = { type: 'stop_server' };
                sendWebSocketMessage(request);
                showNotification('正在停止服务器...', 'info');
            }
        }
        
        // 发送广播消息
        function sendBroadcast() {
            const broadcastMessage = document.getElementById('broadcastMessage').value.trim();
            
            if (!broadcastMessage) {
                showNotification('请输入广播消息内容', 'error');
                return;
            }
            
            // 检查消息长度
            if (broadcastMessage.length > 500) {
                showNotification('消息长度不能超过500个字符', 'error');
                return;
            }
            
            const request = {
                type: 'broadcast',
                message: broadcastMessage,
                sender: username,
                sender_id: clientId
            };
            
            sendWebSocketMessage(request);
            showNotification('广播消息已发送', 'success');
            
            // 清空输入框
            document.getElementById('broadcastMessage').value = '';
        }
        
        // 清空聊天记录
        function clearChat() {
            chatArea.innerHTML = '';
            messageCount = 0;
            messageCountElement.textContent = '0';
            addMessage('系统', '聊天记录已清空', 'system', true);
        }
        
        // 页面加载完成后自动连接
/*         window.onload = function() {
            // 延迟1秒后自动连接，确保所有DOM元素都已加载完成
            setTimeout(function() {
                connect();
            }, 1000);
        }; */
        
        // 发送全局广播
        function sendGlobalBroadcast() {
            const message = prompt('请输入要广播的消息：');
            if (message) {
                const request = {
                    type: 'global_broadcast',
                    message: message,
                    sender: username,
                    sender_id: clientId
                };
                
                sendWebSocketMessage(request);
                showNotification('全局广播已发送', 'success');
            }
        }
        
        // 事件监听器绑定
        connectBtn.addEventListener('click', connect);
        disconnectBtn.addEventListener('click', disconnect);
        
        sendBtn.addEventListener('click', sendMessage);
        messageInput.addEventListener('keypress', (e) => {
            if (e.key === 'Enter' && !e.shiftKey) {
                e.preventDefault();
                sendMessage();
            }
        });
        
        fileInput.addEventListener('change', (e) => {
            if (e.target.files.length > 0) {
                sendFile(e.target.files[0]);
                // 重置文件输入
                e.target.value = '';
            }
        });
        
        // 房间管理按钮
        createRoomBtn.addEventListener('click', createRoom);
        createRoomBtn2.addEventListener('click', createRoom);
        leaveRoomBtn.addEventListener('click', leaveRoom);
        refreshRoomsBtn.addEventListener('click', refreshRooms);
        joinRoomBtn.addEventListener('click', joinRoom);
        deleteRoomBtn.addEventListener('click', deleteRoom);
        
        // 用户管理按钮
        setPermissionBtn.addEventListener('click', setPermission);
        getPermissionBtn.addEventListener('click', getPermission);
        kickUserBtn.addEventListener('click', kickUser);
        listUsersBtn.addEventListener('click', listUsers);
        refreshUsersBtn.addEventListener('click', refreshUsers);
        
        // 管理员按钮
        getMetricsBtn.addEventListener('click', getMetrics);
        getAllRoomsBtn.addEventListener('click', getAllRooms);
        stopServerBtn.addEventListener('click', stopServer);
        sendBroadcastBtn.addEventListener('click', sendBroadcast);
        
        // 其他按钮
        clearChatBtn.addEventListener('click', clearChat);
        broadcastBtn.addEventListener('click', sendGlobalBroadcast);
        
        // 初始化
        disableControls();
        
        // 自动填充示例数据
        document.getElementById('clientId').value = Math.floor(1000 + Math.random() * 9000);
        document.getElementById('username').value = "用户" + document.getElementById('clientId').value;
        
        // 显示欢迎信息
        // addMessage('系统', '欢迎使用WebSocket全功能聊天室！', 'system', true);
        // addMessage('系统', '功能说明：', 'system', true);
        // addMessage('系统', '1. 连接服务器后可以创建/加入房间', 'system', true);
        // addMessage('系统', '2. 支持文本和文件消息发送', 'system', true);
        // addMessage('系统', '3. 支持房间管理、用户权限控制', 'system', true);
        // addMessage('系统', '4. 支持服务器状态监控和管理', 'system', true);
        
        // 模拟服务器响应（用于演示）
        setTimeout(() => {
            if (!ws || ws.readyState !== WebSocket.OPEN) {
                addMessage('系统', '提示：输入用户名称后点击"连接服务器"按钮连接到WebSocket服务器', 'system', true);
            }
        }, 2000);
    </script>
</body>
</html>